package com.crm.config.security;

import com.crm.config.filter.JwtAuthenticationFilter;
import com.crm.config.security.handler.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import static org.springframework.security.config.Customizer.withDefaults;

/**
 * @author junxian.dou
 * @Package：com.crm.config
 * @Project：springboot-crm
 * @name：SecurityFilterChain
 * @Date：2024/11/25 11:44
 * @Filename：SecurityFilterChain
 * @verson 1.0.0
 * @desc
 */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public DBUserDetailsManager userDetailsService() {
        DBUserDetailsManager manager = new DBUserDetailsManager();
        return manager;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    @Bean
    public AuthenticationManager authenticationManager(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder);
        return new ProviderManager(authenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        http.authorizeHttpRequests()
                .mvcMatchers("/user/login",
                        "/doc.html", "/swagger-ui/**",
                        "/v2/api-docs", "/webjars/**",
                        "/swagger-resources/**",
                        "/favicon.ico","/image/**")

                .permitAll()
                .anyRequest()
                .authenticated();
        http.exceptionHandling()
                .authenticationEntryPoint(new MyAuthenticationEntryPoint())
                .accessDeniedHandler(new MyAuthenticationFailureHandler());
        http.logout().addLogoutHandler(new CustomLogoutHandler())
                .invalidateHttpSession(true)  // 注销时使 HTTP 会话失效
                .clearAuthentication(true) // 清除认证信息
                .logoutSuccessHandler(new MyLogoutSuccessHandler());
        http.csrf().disable();
        //跨域
//        http.cors(withDefaults());
        //不创建session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }


}
